package com.dippy.common.exception;

import com.dippy.common.lang.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.ShiroException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/*
@RestControllerAdvice:当我们定义了一个自定义返回参数格式时，希望得到统一的返回，如果在运行时发现了异常，也希望将异常统一返回
        拦截异常并统一处理
        让我们的异常得到期望的返回格式
如果全部异常处理返回json，那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ，
这样在方法上就可以不需要添加 @ResponseBody。
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandle {


    /**
     * 最大范围的异常运行时异常
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)// 状态码，  BAD_REQUEST代表400，
    @ExceptionHandler(value = RuntimeException.class)
    public Result handler(RuntimeException e) {
        log.error("运行时异常：----------{}", e);
        return Result.fail(e.getMessage());
    }

    /**
     *  Shiro异常
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.UNAUTHORIZED)// 状态码，  UNAUTHORIZED代表401， 可以用来代表权限不够等
    @ExceptionHandler(value = ShiroException.class)
    public Result handler(ShiroException e) {
        log.error("Shiro异常：----------{}", e);
        return Result.fail(401,e.getMessage(),null);
    }

    /**
     * 实体类校验异常处理
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.UNAUTHORIZED)// 状态码，  UNAUTHORIZED代表401， 可以用来代表权限不够等
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handler(MethodArgumentNotValidException e) {
        log.error("实体校验异常：----------{}", e);

        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();

        return Result.fail(objectError.getDefaultMessage());
    }

    /**
     * 断言异常
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.UNAUTHORIZED)// 状态码，  UNAUTHORIZED代表401， 可以用来代表权限不够等
    @ExceptionHandler(value = IllegalArgumentException.class)
    public Result handler(IllegalArgumentException e) {
        log.error("断言的异常：----------{}", e);
        return Result.fail(e.getMessage());
    }




}
